package com.wryyyyy.real.impl;

import com.influxdb.client.InfluxDBClient;
import com.influxdb.client.QueryApi;
import com.influxdb.query.FluxTable;
import com.wryyyyy.entity.PureWaterQuality;
import com.wryyyyy.real.IPureWaterDao;
import com.wryyyyy.utils.FluxFilter;
import com.wryyyyy.utils.FluxResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

import static com.wryyyyy.utils.SystemConstants.FOUL_WATER_BUCKET;
import static com.wryyyyy.utils.SystemConstants.PURE_WATER_BUCKET;

@Slf4j
@Component
public class PureWaterDao implements IPureWaterDao {
    @Resource
    private InfluxDBClient influxDBClient;

    @Override
    public Double getPassingRate(List<String> countryIds) {
        QueryApi queryApi = influxDBClient.getQueryApi();

        StringBuilder countryIdFilter = FluxFilter.getCountryIdFilter(countryIds);

        String flux = "t1=from(bucket: \""+PURE_WATER_BUCKET+"\")\n" +
                "  |> range(start: -24h)\n" +
                "  |> filter(fn: (r) => r[\"_measurement\"] == \"pure_water_quality\")\n" +
                countryIdFilter + "\n" +
                "  |> map(fn: (r)=> {\n" +
                "      return if ((r[\"_field\"] == \"TDS\" and r[\"_value\"] > 1000) or (r[\"_field\"] == \"hardness\" and r[\"_value\"] > 450) or (r[\"_field\"] == \"turbidity\" and r[\"_value\"] > 1) or (r[\"_field\"] == \"pH\" and (r[\"_value\"] < 6.5 or r[\"_value\"] > 8.5)))\n" +
                "      then {\"passing\": 0} else {\"passing\":1}\n" +
                "    })\n" +
                "   |> sum(column: \"passing\")\n" +
                "t2=from(bucket: \"pure_water\")\n" +
                "  |> range(start: -24h)\n" +
                "  |> filter(fn: (r) => r[\"_measurement\"] == \"pure_water_quality\")\n" +
                "  |> map(fn: (r)=> {\n" +
                "      return {\"total\": 1}\n" +
                "    })\n" +
                "  |> sum(column: \"total\")\n" +
                "  union(tables: [t1,t2])\n";

        List<FluxTable> tables = queryApi.query(flux);

        return FluxResult.toPercentage(tables);
    }

    @Override
    public PureWaterQuality getContent(List<String> countryIds) {
        QueryApi queryApi = influxDBClient.getQueryApi();

        StringBuilder countryIdFilter = FluxFilter.getCountryIdFilter(countryIds);

        String flux = "from(bucket: \""+PURE_WATER_BUCKET+"\")\n" +
                "  |> range(start: -24h)\n" +
                "  |> filter(fn: (r) => r[\"_measurement\"] == \"pure_water_quality\")\n" +
                countryIdFilter + "\n" +
                "  |> drop(columns: [\"country_id\"])\n" +
                "  |> mean()\n" +
                "  |> yield(name: \"result\")";

        List<FluxTable> tables = queryApi.query(flux);

        return FluxResult.toBean(tables, PureWaterQuality.class);
    }

    @Override
    public Map<LocalDateTime, Double> getAmount(List<String> countryIds) {
        QueryApi queryApi = influxDBClient.getQueryApi();

        StringBuilder countryIdFilter = FluxFilter.getCountryIdFilter(countryIds);

        String flux = "from(bucket: \""+PURE_WATER_BUCKET+"\")\n" +
                "  |> range(start: -24h)\n" +
                "  |> filter(fn: (r) => r[\"_measurement\"] == \"pure_water_amount\")\n" +
                countryIdFilter + "\n" +
                "  |> drop(columns: [\"country_id\"])\n" +
                "  |> window(every: 2h)\n" +
                "  |> sum()\n" +
                "  |> yield(name: \"result\")";

        List<FluxTable> tables = queryApi.query(flux);

        return FluxResult.toEach(tables);
    }
}